package com.example.lettcode._20241012;

import java.util.*;
import java.util.stream.Stream;

/*
219. 存在重复元素 II
给你一个整数数组 nums 和一个整数 k ，判断数组中是否存在两个 不同的索引 i 和 j ，满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在，返回 true ；否则，返回 false 。

示例 1：
输入：nums = [1,2,3,1], k = 3
输出：true

示例 2：
输入：nums = [1,0,1,1], k = 1
输出：true

示例 3：
输入：nums = [1,2,3,1,2,3], k = 2
输出：false
 */
public class Cun_zai_chong_fu_yuan_su {

    public static void main(String[] args) {
        int[] nums = {1,2,3,1};
        int k = 3;
        System.out.println(containsNearbyDuplicate3(nums, k));
    }

    public static boolean containsNearbyDuplicate(int[] nums, int k) {
        int n = nums.length;
        Map<Integer, List<Integer>> map = new HashMap<>(n);

        for (int i = 0; i < n; i++) {
            if (map.containsKey(nums[i])) {
                map.get(nums[i]).add(i);
                continue;
            }
            List<Integer> list = new ArrayList<>(n);
            list.add(i);
            map.put(nums[i], list);
        }

        for (Map.Entry<Integer, List<Integer>> map2 : map.entrySet()) {
            List<Integer> value = map2.getValue();
            if (value.size() == 1) {
                continue;
            }
            int min = Integer.MAX_VALUE;
            for (int i = 1; i < value.size(); i++) {
                int prev = value.get(i-1);
                int current = value.get(i);
                min = Math.min(min, current - prev);
            }
            if (min <= k) {
                return true;
            }
        }
        return false;
    }


    public static boolean containsNearbyDuplicate2(int[] nums, int k) {
        int n = nums.length;
        Map<Integer, Integer> map = new HashMap<>(n);

        for (int i = 0; i < n; i++) {
            if (map.containsKey(nums[i])) {
                Integer integer = map.get(nums[i]);
                if ((i - integer) <= k) {
                    return true;
                }
            }
            map.put(nums[i], i);
        }
        return false;
    }

    public static boolean containsNearbyDuplicate3(int[] nums, int k) {
        int n = nums.length;
        Set<Integer> set = new HashSet<>();

        for (int i = 0; i < n; i++) {
            if (i > k) {
                set.remove(nums[i-k-1]);
            }

            if (!set.add(nums[i])) {
                return true;
            }
        }

        return false;
    }
}
